package ch.subgate.spritestudio.widgets;

import java.util.ArrayList;

import ch.subgate.spritestudio.tools.OnHueChangedListener;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Shader;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

public class HPickerView extends View {
	
	private float mWidth;
	private float mHeight;
	
	/** Hue listeners */
	private ArrayList<OnHueChangedListener> mHueListeners;
	
	/** Paint object for color gradient */
	private Paint mPaint;
	
	private Paint mLinePaint;
	
	/** Current hue value */
	private float mHue;
	
	/** Select y value */
	private float mSelectX;
	
	public HPickerView(Context context, AttributeSet attrs) {
		super(context, attrs);
		
		mWidth = 0.0f;
		mHeight = 0.0f;
		
		//Initialize the list of listeners
		mHueListeners = new ArrayList<OnHueChangedListener>();
		
		//Initialize paint object
		mPaint = new Paint();
		mLinePaint = new Paint();
		
		//Set hue and select value
		mHue = 1.0f;
		mSelectX = 0.0f;
	}
	
	/** Method is invoked when surface needs to redraw */
	@Override
	public void onDraw(Canvas canvas) {
		//Set the shader for the paint object
		mPaint.setShader(this.getShader());
		
		//Draw the gradient
		canvas.drawRect(
				0.0f,
				0.0f,
				mWidth,
				mHeight,
				mPaint);
		
		//Draw the slider
		mLinePaint.setStrokeWidth(9.0f);
		mLinePaint.setColor(0x99000000);
		canvas.drawLine(
				mSelectX, 0.0f,
				mSelectX, mHeight,
				mLinePaint);
		mLinePaint.setStrokeWidth(3.0f);
		mLinePaint.setColor(0xffffffff);
		canvas.drawLine(
				mSelectX, 0.0f,
				mSelectX, mHeight,
				mLinePaint);
	}
	
	@Override
	protected void onSizeChanged(int w, int h, int oldw, int oldh) {
		super.onSizeChanged(w, h, oldw, oldh);
		mWidth = w;
		mHeight = h;
	}
	
	/** Method is invoked when surface receives a motion event */
	@Override
	public boolean onTouchEvent(MotionEvent e) {
		float eventx;
		
		if (e.getX() > mWidth) {
			eventx = mWidth;
		}
		else if (e.getX() < 0.0f) {
			eventx = 0.0f;
		}
		else {
			eventx = e.getX();
		}
		
		switch (e.getAction() & MotionEvent.ACTION_MASK) {
		case MotionEvent.ACTION_DOWN:
			mSelectX = eventx;
			break;
		case MotionEvent.ACTION_MOVE:
			mSelectX = eventx;
			break;
		case MotionEvent.ACTION_UP:
			mSelectX = eventx;
			mHue = (mSelectX / mWidth) * 360.0f;
			onHueChanged();
			break;
		}
		
		//Request the surface to redraw
		invalidate();
		
		return true;
	}
	
	/** Method is invoked when hue component changes */
	public void onHueChanged() {
		if (!mHueListeners.isEmpty()) {
			for (OnHueChangedListener listener : mHueListeners) {
				listener.onHueChanged(mHue);
			}
		}
	}
	
	public LinearGradient getShader() {
		//Create the hue color array
		int[] colors = {
				0xffff0000,
				0xffffff00,
				0xff00ff00,
				0xff00ffff,
				0xff0000ff,
				0xffff00ff,
				0xffff0000};
		
		//Set up the shader to draw the gradient
		return new LinearGradient(
				0.0f,
				0.0f,
				mWidth,
				0.0f,
				colors,
				null,
				Shader.TileMode.CLAMP);
	}
	
	/** Method to register a listener for the hue component */
	public void registerHueChangedListener(OnHueChangedListener listener) {
		mHueListeners.add(listener);
	}
	
	/** Setter method for hue value */
	public void setHue(float hue) {
		mHue = hue;
		mSelectX = (mHue / 360.0f) * mWidth;
		
		onHueChanged();
		
		//Request the surface to redraw
		invalidate();
	}
}
